extends CharacterBody2D

signal collected(value)

@export var value: int = 1  # 金币价值
@export var collect_sound: AudioStream  # 收集音效
@export var lifetime: float = 30.0  # 金币在场景中存在的时间（秒）

var gravity = 400  # 重力加速度
var bounce_factor = 0.5  # 减小反弹系数，从0.7改为0.5
var friction = 0.95  # 空气阻力系数
var bounce_threshold = 5  # 反弹停止阈值
var is_being_collected = false
var timer = 0.0
var sparkle_chance = 0.02  # 每帧有2%的概率切换到闪烁动画
var stabilize_timer = 0.0  # 用于稳定金币的计时器

func _ready():
	print("金币初始化 - 值:", value)
	# 设置收集音效
	if collect_sound:
		$AudioStreamPlayer.stream = collect_sound
	
	# 设置自动销毁计时器
	if lifetime > 0:
		timer = lifetime
	
	# 确保动画正在播放
	$AnimatedSprite2D.play()
	
	# 不再添加随机旋转，保持金币直立
	rotation = 0
	
	# 设置物理层和掩码，确保与玩家正确碰撞
	collision_layer = 16  # 第5层，物品层
	collision_mask = 3    # 第1和2层，地形和玩家
	
	# 打印调试信息
	print("金币碰撞层设置 - collision_layer:", collision_layer, ", collision_mask:", collision_mask)
	print("玩家检测器设置 - collision_layer:", $PlayerDetector.collision_layer, ", collision_mask:", $PlayerDetector.collision_mask)
	
	# 增加碰撞检测连接，确保能捕获到玩家碰撞
	$PlayerDetector.connect("body_entered", _on_body_entered)
	
	# 添加定时检查，查看附近是否有玩家
	var timer = Timer.new()
	timer.wait_time = 0.5  # 每0.5秒检查一次
	timer.autostart = true
	timer.one_shot = false
	add_child(timer)
	timer.connect("timeout", check_for_nearby_player)

# 定时检查附近的玩家
func check_for_nearby_player():
	# 如果已经被收集，不再检查
	if is_being_collected:
		return
		
	# 获取所有玩家节点
	var players = get_tree().get_nodes_in_group("player")
	print("检查附近玩家 - 场景中玩家数量:", players.size())
	
	for player in players:
		var distance = global_position.distance_to(player.global_position)
		if distance < 30:  # 如果玩家距离小于30像素
			print("发现附近玩家，距离:", distance, "，尝试收集")
			collect_by_player(player)
			break

func _physics_process(delta):
	if is_being_collected:
		return
	
	# 更新计时器
	if timer > 0:
		timer -= delta
		if timer <= 0:
			# 金币闪烁效果，然后消失
			var tween = create_tween()
			tween.tween_property(self, "modulate:a", 0.0, 0.5)
			tween.tween_callback(queue_free)
			return
	
	# 随机切换到闪烁动画
	if randf() < sparkle_chance and $AnimatedSprite2D.animation != "sparkle":
		$AnimatedSprite2D.animation = "sparkle"
		$AnimatedSprite2D.play()
		
		# 创建一个定时器在闪烁完成后切回默认动画
		await get_tree().create_timer(0.5).timeout
		if is_instance_valid(self) and not is_being_collected:
			$AnimatedSprite2D.animation = "default"
	
	# 应用重力
	velocity.y += gravity * delta
	
	# 应用空气阻力
	velocity.x *= friction
	
	# 如果金币速度很小，则完全停止它，防止抽搐
	if abs(velocity.x) < bounce_threshold and abs(velocity.y) < bounce_threshold and is_on_floor():
		stabilize_timer += delta
		if stabilize_timer > 0.5:  # 如果金币保持低速0.5秒，完全停止它
			velocity = Vector2.ZERO
			set_collision_layer_value(1, false)  # 禁用与其他物体的碰撞
	else:
		stabilize_timer = 0.0
	
	# 每帧重置旋转，保持金币始终直立
	rotation = 0
	
	# 处理移动和碰撞
	var collision = move_and_slide()
	
	# 如果发生碰撞，处理弹跳效果
	if get_slide_collision_count() > 0:
		for i in range(get_slide_collision_count()):
			var collision_info = get_slide_collision(i)
			var normal = collision_info.get_normal()
			var collider = collision_info.get_collider()
			
			# 检查是否与玩家碰撞
			if collider and collider.is_in_group("player"):
				print("检测到与玩家直接碰撞:", collider.name)
				collect_by_player(collider)
				return
				
			# 如果碰到地面（向上的法线）
			if normal.y < -0.5:
				# 反弹处理
				velocity.y = -abs(velocity.y) * bounce_factor
				
				# 如果速度太小，停止垂直移动
				if abs(velocity.y) < bounce_threshold:
					velocity.y = 0
				
				# 水平速度衰减
				velocity.x *= 0.8
				
				# 不再添加随机旋转
				
				# 播放弹跳动画效果，但不影响旋转
				var bounce_scale = min(abs(velocity.y) / 300, 0.2)  # 减小弹跳动画幅度
				var tween = create_tween()
				tween.tween_property(self, "scale", Vector2(1.5 + bounce_scale, 1.5 - bounce_scale), 0.1)
				tween.tween_property(self, "scale", Vector2(1.5, 1.5), 0.2)
			
			# 如果碰到墙壁（水平法线）
			elif abs(normal.x) > 0.5:
				# 水平反弹
				velocity.x = -velocity.x * bounce_factor
				
				# 如果速度太小，停止水平移动
				if abs(velocity.x) < bounce_threshold:
					velocity.x = 0

# 弹出效果，用于从宝箱中弹出
func pop_out(initial_velocity = Vector2.ZERO):
	print("金币开始弹出，初始速度:", initial_velocity)
	velocity = initial_velocity
	
	# 创建一个缓动效果，让金币变大再恢复正常大小
	var tween = create_tween()
	tween.tween_property(self, "scale", Vector2(2.0, 2.0), 0.1)
	tween.tween_property(self, "scale", Vector2(1.5, 1.5), 0.2)
	
	# 加快动画速度，给予更活跃的感觉
	$AnimatedSprite2D.speed_scale = 1.5
	
	# 不再添加随机旋转，保持金币直立
	rotation = 0

func collect():
	if is_being_collected:
		return
	
	is_being_collected = true
	
	# 禁用碰撞
	$CollisionShape2D.set_deferred("disabled", true)
	$PlayerDetector/CollisionShape2D.set_deferred("disabled", true)
	
	# 播放收集音效
	if $AudioStreamPlayer.stream:
		$AudioStreamPlayer.play()
	
	# 发送收集信号
	emit_signal("collected", value)
	
	# 切换到闪烁动画
	$AnimatedSprite2D.animation = "sparkle"
	$AnimatedSprite2D.speed_scale = 2.0
	
	# 创建收集动画
	var tween = create_tween()
	tween.tween_property(self, "scale", Vector2(2.0, 2.0), 0.1)
	tween.tween_property(self, "scale", Vector2(0, 0), 0.2)
	tween.tween_callback(queue_free)

# 当玩家进入金币的检测区域时
func _on_body_entered(body):
	# 检查碰撞的是否为玩家
	print("金币检测到碰撞 - 对象:", body.name, ", 组:", body.get_groups())
	if body.is_in_group("player"):
		print("金币检测到玩家，正在收集...")
		collect_by_player(body)

# 由玩家收集金币
func collect_by_player(player):
	# 先执行收集动画
	collect()
	
	# 如果玩家有add_coins方法，调用它
	if player.has_method("add_coins"):
		print("调用玩家的add_coins方法，金币值:", value)
		player.add_coins(value)
	else:
		print("警告：玩家没有add_coins方法，可用方法:", player.get_method_list()) 
